use std::io::process::ExitStatus;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, Human};
+use cargo::util::{CliResult, CliError, Human, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
Compilation can be customized with the `bench` profile in the manifest.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
- let mut ops = ops::TestOptions {
+ let ops = ops::TestOptions {
name: options.flag_bench.as_ref().map(|s| s.as_slice()),
no_run: options.flag_no_run,
compile_opts: ops::CompileOptions {
env: "bench",
- shell: shell,
+ config: config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|s| s.as_slice()),
dev_deps: true,
},
};
- let err = try!(ops::run_benches(&root, &mut ops,
+ let err = try!(ops::run_benches(&root, &ops,
options.arg_args.as_slice()).map_err(|err| {
CliError::from_boxed(err, 101)
}));
use std::os;
-use cargo::core::MultiShell;
use cargo::ops::CompileOptions;
use cargo::ops;
use cargo::util::important_paths::{find_root_manifest_for_cwd};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options {
the --release flag will use the `release` profile instead.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-build; args={:?}", os::args());
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
"compile"
};
- let mut opts = CompileOptions {
+ let opts = CompileOptions {
env: env,
- shell: shell,
+ config: config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| t.as_slice()),
dev_deps: false,
exec_engine: None,
};
- ops::compile(&root, &mut opts).map(|_| None).map_err(|err| {
+ ops::compile(&root, &opts).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101)
})
}
use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
-use cargo::util::{CliError, CliResult, lev_distance};
+use cargo::util::{CliError, CliResult, lev_distance, Config};
#[derive(RustcDecodable)]
struct Flags {
$mac!(bench);
$mac!(build);
$mac!(clean);
- $mac!(config_for_key);
- $mac!(config_list);
$mac!(doc);
$mac!(fetch);
$mac!(generate_lockfile);
because they are fundamental (and intertwined). Other commands can rely
on this top-level information.
*/
-fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
+fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo; args={:?}", os::args());
- shell.set_verbose(flags.flag_verbose);
+ config.shell().set_verbose(flags.flag_verbose);
if flags.flag_list {
println!("Installed Commands:");
let (mut args, command) = match flags.arg_command.as_slice() {
"" | "help" if flags.arg_args.len() == 0 => {
- shell.set_verbose(true);
+ config.shell().set_verbose(true);
let args = &[os::args()[0].clone(), "-h".to_string()];
- let r = cargo::call_main_without_stdin(execute, shell, USAGE, args,
+ let r = cargo::call_main_without_stdin(execute, config, USAGE, args,
false);
- cargo::process_executed(r, shell);
+ cargo::process_executed(r, &mut **config.shell());
return Ok(None)
}
"help" if flags.arg_args[0].as_slice() == "-h" ||
macro_rules! cmd{ ($name:ident) => (
if command.as_slice() == stringify!($name).replace("_", "-").as_slice() {
mod $name;
- shell.set_verbose(true);
- let r = cargo::call_main_without_stdin($name::execute, shell,
+ config.shell().set_verbose(true);
+ let r = cargo::call_main_without_stdin($name::execute, config,
$name::USAGE,
args.as_slice(),
false);
- cargo::process_executed(r, shell);
+ cargo::process_executed(r, &mut **config.shell());
return Ok(None)
}
) }
each_subcommand!(cmd);
- execute_subcommand(command.as_slice(), args.as_slice(), shell);
+ execute_subcommand(command.as_slice(), args.as_slice(),
+ &mut **config.shell());
Ok(None)
}
Some(command) => command,
None => {
let msg = match find_closest(cmd) {
- Some(closest) => format!("No such subcommand\n\n\tDid you mean `{}`?\n", closest),
+ Some(closest) => format!("No such subcommand\n\n\t\
+ Did you mean `{}`?\n", closest),
None => "No such subcommand".to_string()
};
return handle_error(CliError::new(msg, 127), shell)
use std::os;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
and its format, see the `cargo help pkgid` command.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
debug!("executing; cmd=cargo-clean; args={:?}", os::args());
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- let mut opts = ops::CleanOptions {
- shell: shell,
+ let opts = ops::CleanOptions {
+ config: config,
spec: options.flag_package.as_ref().map(|s| s.as_slice()),
target: options.flag_target.as_ref().map(|s| s.as_slice()),
};
- ops::clean(&root, &mut opts).map(|_| None).map_err(|err| {
+ ops::clean(&root, &opts).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101)
})
}
+++ /dev/null
-use std::os;
-use std::collections::HashMap;
-
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, config};
-
-#[derive(RustcDecodable)]
-struct ConfigForKeyFlags {
- flag_human: bool,
- flag_key: String,
-}
-
-#[derive(RustcEncodable)]
-struct ConfigOut {
- values: HashMap<String, config::ConfigValue>
-}
-
-pub const USAGE: &'static str = "
-Usage:
- cargo config-for-key --human --key=<key>
- cargo config-for-key -h | --help
-
-Options:
- -h, --help Print this message
-";
-
-pub fn execute(args: ConfigForKeyFlags,
- _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
- let cwd = try!(os::getcwd().map_err(|_|
- CliError::new("Couldn't determine the current working directory", 1)));
- let value = try!(config::get_config(cwd, args.flag_key.as_slice()).map_err(|_| {
- CliError::new("Couldn't load configuration", 1)
- }));
-
- if args.flag_human {
- println!("{:?}", value);
- Ok(None)
- } else {
- let mut map = HashMap::new();
- map.insert(args.flag_key.clone(), value);
- Ok(Some(ConfigOut { values: map }))
- }
-}
+++ /dev/null
-use std::os;
-use std::collections::HashMap;
-
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, config};
-
-#[derive(RustcDecodable)]
-struct ConfigListFlags {
- flag_human: bool,
-}
-
-#[derive(RustcEncodable)]
-struct ConfigOut {
- values: HashMap<String, config::ConfigValue>
-}
-
-pub const USAGE: &'static str = "
-Usage:
- cargo config-list --human
- cargo config-list -h | --help
-
-Options:
- -h, --help Print this message
-";
-
-pub fn execute(args: ConfigListFlags,
- _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
- let cwd = try!(os::getcwd().map_err(|_|
- CliError::new("Couldn't determine the current working directory", 1)));
- let configs = try!(config::all_configs(cwd).map_err(|_|
- CliError::new("Couldn't load configuration", 1)));
-
- if args.flag_human {
- for (key, value) in configs.iter() {
- println!("{} = {:?}", key, value);
- }
- Ok(None)
- } else {
- Ok(Some(ConfigOut { values: configs }))
- }
-}
use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
the `cargo help pkgid` command.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
open_result: options.flag_open,
compile_opts: ops::CompileOptions {
env: if options.flag_no_deps {"doc"} else {"doc-all"},
- shell: shell,
+ config: config,
jobs: options.flag_jobs,
target: None,
dev_deps: false,
use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_cwd;
#[derive(RustcDecodable)]
all updated.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- try!(ops::fetch(&root, shell).map_err(|e| {
+ try!(ops::fetch(&root, config).map_err(|e| {
CliError::from_boxed(e, 101)
}));
Ok(None)
use std::os;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_cwd;
#[derive(RustcDecodable)]
-v, --verbose Use verbose output
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-generate-lockfile; args={:?}", os::args());
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- ops::generate_lockfile(&root, shell)
+ ops::generate_lockfile(&root, config)
.map(|_| None).map_err(|err| CliError::from_boxed(err, 101))
}
-use cargo::core::MultiShell;
use cargo::core::source::{Source, SourceId, GitReference};
use cargo::sources::git::{GitSource};
use cargo::util::{Config, CliResult, CliError, human, ToUrl};
-v, --verbose Use verbose output
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let Options { flag_url: url, flag_reference: reference, .. } = options;
let url = try!(url.as_slice().to_url().map_err(|e| {
let reference = GitReference::Branch(reference.to_string());
let source_id = SourceId::for_git(&url, reference);
- let mut config = try!(Config::new(shell, None, None).map_err(|e| {
- CliError::from_boxed(e, 1)
- }));
- let mut source = GitSource::new(&source_id, &mut config);
+ let mut source = GitSource::new(&source_id, config);
try!(source.update().map_err(|e| {
CliError::new(format!("Couldn't update {:?}: {:?}", source, e), 1)
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options;
-h, --help Print this message
";
-pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(_: Options, _: &Config) -> CliResult<Option<()>> {
// This is a dummy command just so that `cargo help help` works.
// The actual delegation of help flag to subcommands is handled by the
// cargo command.
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, human, ChainError};
+use cargo::util::{CliResult, CliError, human, ChainError, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
}
pub fn execute(flags: LocateProjectFlags,
- _: &mut MultiShell) -> CliResult<Option<ProjectLocation>> {
+ _: &Config) -> CliResult<Option<ProjectLocation>> {
let root = try!(find_root_manifest_for_cwd(flags.flag_manifest_path));
let string = try!(root.as_str()
use std::io;
use cargo::ops;
-use cargo::core::{MultiShell, SourceId, Source};
+use cargo::core::{SourceId, Source};
use cargo::sources::RegistrySource;
use cargo::util::{CliResult, CliError, Config};
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let token = match options.arg_token.clone() {
Some(token) => token,
None => {
let err = (|:| {
- let config = try!(Config::new(shell, None, None));
- let src = try!(SourceId::for_central());
- let mut src = RegistrySource::new(&src, &config);
+ let src = try!(SourceId::for_central(config));
+ let mut src = RegistrySource::new(&src, config);
try!(src.update());
let config = try!(src.config());
let host = options.flag_host.clone().unwrap_or(config.api);
};
let token = token.as_slice().trim().to_string();
- try!(ops::registry_login(shell, token).map_err(|e| {
+ try!(ops::registry_login(config, token).map_err(|e| {
CliError::from_boxed(e, 101)
}));
Ok(None)
use std::os;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options {
-v, --verbose Use verbose output
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-new; args={:?}", os::args());
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
let Options { flag_bin, arg_path, flag_vcs, .. } = options;
bin: flag_bin,
};
- ops::new(opts, shell).map(|_| None).map_err(|err| {
+ ops::new(opts, config).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101)
})
}
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options {
versions, and also modify the set of owners, so take caution!
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let opts = ops::OwnersOptions {
krate: options.arg_crate,
token: options.flag_token,
to_remove: options.flag_remove,
list: options.flag_list,
};
- try!(ops::modify_owners(shell, &opts).map_err(|e| {
+ try!(ops::modify_owners(config, &opts).map_err(|e| {
CliError::from_boxed(e, 101)
}));
Ok(None)
use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_cwd;
#[derive(RustcDecodable)]
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- ops::package(&root, shell,
+ ops::package(&root, config,
!options.flag_no_verify,
options.flag_list,
!options.flag_no_metadata).map(|_| None).map_err(|err| {
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
";
pub fn execute(options: Options,
- shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+ config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone()));
let spec = options.arg_spec.as_ref().map(|s| s.as_slice());
- let spec = try!(ops::pkgid(&root, spec, shell).map_err(|err| {
+ let spec = try!(ops::pkgid(&root, spec, config).map_err(|err| {
CliError::from_boxed(err, 101)
}));
println!("{}", spec);
use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_cwd;
#[derive(RustcDecodable)]
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let Options {
flag_token: token,
flag_host: host,
} = options;
let root = try!(find_root_manifest_for_cwd(flag_manifest_path.clone()));
- ops::publish(&root, shell, token, host, !no_verify).map(|_| None).map_err(|err| {
+ ops::publish(&root, config, token, host, !no_verify).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101)
})
}
-use cargo::core::{MultiShell, Package, Source};
-use cargo::util::{CliResult, CliError};
+use cargo::core::{Package, Source};
+use cargo::util::{CliResult, CliError, Config};
use cargo::sources::{PathSource};
#[derive(RustcDecodable)]
-v, --verbose Use verbose output
";
-pub fn execute(options: Options, _: &mut MultiShell) -> CliResult<Option<Package>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<Package>> {
let path = Path::new(options.flag_manifest_path.as_slice());
- let mut source = try!(PathSource::for_path(&path).map_err(|e| {
+ let mut source = try!(PathSource::for_path(&path, config).map_err(|e| {
CliError::new(e.description(), 1)
}));
use std::io::process::ExitStatus;
use cargo::ops;
-use cargo::core::{MultiShell};
use cargo::core::manifest::TargetKind;
-use cargo::util::{CliResult, CliError, human};
+use cargo::util::{CliResult, CliError, human, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
All of the trailing arguments are passed as to the binary to run.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
let env = match (options.flag_release, options.flag_example.is_some()) {
(false, false) => "compile"
};
- let mut compile_opts = ops::CompileOptions {
+ let compile_opts = ops::CompileOptions {
env: env,
- shell: shell,
+ config: config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| t.as_slice()),
dev_deps: true,
let err = try!(ops::run(&root,
target_kind,
name,
- &mut compile_opts,
+ &compile_opts,
options.arg_args.as_slice()).map_err(|err| {
CliError::from_boxed(err, 101)
}));
use cargo::ops;
-use cargo::core::{MultiShell};
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options {
-v, --verbose Use verbose output
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
let Options {
flag_host: host,
arg_query: query,
..
} = options;
- ops::search(query.as_slice(), shell, host)
+ ops::search(query.as_slice(), config, host)
.map(|_| None)
.map_err(|err| CliError::from_boxed(err, 101))
}
use std::io::process::ExitStatus;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError, Human};
+use cargo::util::{CliResult, CliError, Human, Config};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
#[derive(RustcDecodable)]
Compilation can be configured via the `test` profile in the manifest.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
- let mut ops = ops::TestOptions {
+ let ops = ops::TestOptions {
name: options.flag_test.as_ref().map(|s| s.as_slice()),
no_run: options.flag_no_run,
compile_opts: ops::CompileOptions {
env: "test",
- shell: shell,
+ config: config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|s| s.as_slice()),
dev_deps: true,
},
};
- let err = try!(ops::run_tests(&root, &mut ops,
+ let err = try!(ops::run_tests(&root, &ops,
options.arg_args.as_slice()).map_err(|err| {
CliError::from_boxed(err, 101)
}));
use std::os;
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_cwd;
#[derive(RustcDecodable)]
struct Options {
- arg_spec: Option<String>,
flag_package: Option<String>,
flag_aggressive: bool,
flag_precise: Option<String>,
Usage:
cargo update [options]
- cargo update [options] <spec>
Options:
-h, --help Print this message
For more information about package id specifications, see `cargo help pkgid`.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-update; args={:?}", os::args());
- shell.set_verbose(options.flag_verbose);
+ config.shell().set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
- let spec = if options.arg_spec.is_some() {
- let _ = shell.warn("`cargo update foo` has been deprecated in favor \
- of `cargo update -p foo`. This functionality \
- will be removed in the future");
- options.arg_spec.as_ref()
- } else {
- options.flag_package.as_ref()
- };
+ let spec = options.flag_package.as_ref();
- let mut update_opts = ops::UpdateOptions {
+ let update_opts = ops::UpdateOptions {
aggressive: options.flag_aggressive,
precise: options.flag_precise.as_ref().map(|s| s.as_slice()),
to_update: spec.map(|s| s.as_slice()),
- shell: shell,
+ config: config,
};
- ops::update_lockfile(&root, &mut update_opts)
+ ops::update_lockfile(&root, &update_opts)
.map(|_| None).map_err(|err| CliError::from_boxed(err, 101))
}
use std::io::File;
use std::os;
-use cargo::core::MultiShell;
-use cargo::util::CliResult;
+use cargo::util::{CliResult, Config};
pub type Error = HashMap<String, String>;
-v, --verbose Use verbose output
";
-pub fn execute(args: Flags,
- shell: &mut MultiShell) -> CliResult<Option<Error>> {
- shell.set_verbose(args.flag_verbose);
+pub fn execute(args: Flags, config: &Config) -> CliResult<Option<Error>> {
+ config.shell().set_verbose(args.flag_verbose);
let file = Path::new(args.flag_manifest_path);
let contents = match File::open(&file).read_to_string() {
use std::os;
use cargo;
-use cargo::core::MultiShell;
-use cargo::util::CliResult;
+use cargo::util::{CliResult, Config};
#[derive(RustcDecodable)]
struct Options;
-v, --verbose Use verbose output
";
-pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
+pub fn execute(_: Options, _: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-version; args={:?}", os::args());
println!("{}", cargo::version());
use cargo::ops;
-use cargo::core::MultiShell;
-use cargo::util::{CliResult, CliError};
+use cargo::util::{CliResult, CliError, Config};
#[derive(RustcDecodable)]
struct Options {
crates to be locked to any yanked version.
";
-pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
- shell.set_verbose(options.flag_verbose);
- try!(ops::yank(shell,
+pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
+ config.shell().set_verbose(options.flag_verbose);
+ try!(ops::yank(config,
options.arg_crate,
options.flag_vers,
options.flag_token,
mod tests {
use core::{PackageId, SourceId};
use super::{PackageIdSpec, url};
+ use url::Url;
use semver::Version;
#[test]
#[test]
fn matching() {
- let sid = SourceId::for_central().unwrap();
+ let url = Url::parse("http://example.com").unwrap();
+ let sid = SourceId::for_registry(&url);
let foo = PackageId::new("foo", "1.2.3", &sid).unwrap();
let bar = PackageId::new("bar", "1.2.3", &sid).unwrap();
/// `SourceMap` structure contained within which is a mapping of a `SourceId` to
/// a `Source`. Each `Source` in the map has been updated (using network
/// operations if necessary) and is ready to be queried for packages.
-pub struct PackageRegistry<'a> {
+pub struct PackageRegistry<'a, 'b: 'a> {
sources: SourceMap<'a>,
- config: &'a Config<'a>,
+ config: &'a Config<'b>,
// A list of sources which are considered "overrides" which take precedent
// when querying for packages.
Normal,
}
-impl<'a> PackageRegistry<'a> {
- pub fn new(config: &'a Config<'a>) -> PackageRegistry<'a> {
+impl<'a, 'b> PackageRegistry<'a, 'b> {
+ pub fn new(config: &'a Config<'b>) -> PackageRegistry<'a, 'b> {
PackageRegistry {
sources: SourceMap::new(),
source_ids: HashMap::new(),
}
}
-impl<'a> Registry for PackageRegistry<'a> {
+impl<'a, 'b> Registry for PackageRegistry<'a, 'b> {
fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
let overrides = try!(self.query_overrides(dep));
///
/// This is the main cargo registry by default, but it can be overridden in
/// a `.cargo/config`.
- pub fn for_central() -> CargoResult<SourceId> {
- Ok(SourceId::for_registry(&try!(RegistrySource::url())))
+ pub fn for_central(config: &Config) -> CargoResult<SourceId> {
+ Ok(SourceId::for_registry(&try!(RegistrySource::url(config))))
}
pub fn get_url(&self) -> &Url { &self.inner.url }
Ok(p) => p,
Err(()) => panic!("path sources cannot be remote"),
};
- Box::new(PathSource::new(&path, self)) as Box<Source>
+ Box::new(PathSource::new(&path, self, config)) as Box<Source>
},
Kind::Registry => {
Box::new(RegistrySource::new(self, config)) as Box<Source>
use core::{Shell, MultiShell, ShellConfig};
use term::color::{BLACK, RED};
-pub use util::{CargoError, CliError, CliResult, human};
+pub use util::{CargoError, CliError, CliResult, human, Config};
macro_rules! some {
($e:expr) => (
pub mod util;
pub fn execute_main<T, U, V>(
- exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
+ exec: fn(T, U, &Config) -> CliResult<Option<V>>,
options_first: bool,
usage: &str)
where V: Encodable, T: Decodable, U: Decodable
}
pub fn call_main<T, U, V>(
- exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
- shell: &mut MultiShell,
+ exec: fn(T, U, &Config) -> CliResult<Option<V>>,
+ shell: &Config,
usage: &str,
args: &[String],
options_first: bool) -> CliResult<Option<V>>
}
pub fn execute_main_without_stdin<T, V>(
- exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
+ exec: fn(T, &Config) -> CliResult<Option<V>>,
options_first: bool,
usage: &str)
where V: Encodable, T: Decodable
});
}
-pub fn execute_main_with_args_and_without_stdin<T, V>(
- exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
- options_first: bool,
- usage: &str,
- args: &[String])
- where V: Encodable, T: Decodable
-{
- let mut shell = shell(true);
-
- process_executed(
- call_main_without_stdin(exec, &mut shell, usage, args, options_first),
- &mut shell)
-}
-
pub fn call_main_without_stdin<T, V>(
- exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
- shell: &mut MultiShell,
+ exec: fn(T, &Config) -> CliResult<Option<V>>,
+ shell: &Config,
usage: &str,
args: &[String],
options_first: bool) -> CliResult<Option<V>>
}
fn process<V, F>(mut callback: F)
- where F: FnMut(&[String], &mut MultiShell) -> CliResult<Option<V>>,
+ where F: FnMut(&[String], &Config) -> CliResult<Option<V>>,
V: Encodable
{
let mut shell = shell(true);
- process_executed(callback(os::args().as_slice(), &mut shell), &mut shell)
+ process_executed({
+ match Config::new(&mut shell) {
+ Ok(cfg) => callback(os::args().as_slice(), &cfg),
+ Err(e) => Err(CliError::from_boxed(e, 101)),
+ }
+ }, &mut shell)
}
-pub fn process_executed<T>(result: CliResult<Option<T>>,
- shell: &mut MultiShell)
+pub fn process_executed<T>(result: CliResult<Option<T>>, shell: &mut MultiShell)
where T: Encodable
{
match result {
use std::default::Default;
use std::io::fs::{self, PathExtensions};
-use core::{MultiShell, PackageSet};
+use core::PackageSet;
use core::source::{Source, SourceMap};
use sources::PathSource;
use util::{CargoResult, human, ChainError, Config};
use ops::{self, Layout, Context};
-pub struct CleanOptions<'a> {
+pub struct CleanOptions<'a, 'b: 'a> {
pub spec: Option<&'a str>,
pub target: Option<&'a str>,
- pub shell: &'a mut MultiShell,
+ pub config: &'a Config<'b>,
}
/// Cleans the project from build artifacts.
-pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> {
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+ opts.config));
try!(src.update());
let root = try!(src.get_root_package());
let manifest = root.get_manifest();
let pkgid = try!(resolve.query(spec));
// Translate the PackageId to a Package
- let mut cfg = try!(Config::new(opts.shell, None, None));
let pkg = {
- let mut source = pkgid.get_source_id().load(&mut cfg);
+ let mut source = pkgid.get_source_id().load(opts.config);
try!(source.update());
(try!(source.get(&[pkgid.clone()]))).into_iter().next().unwrap()
};
// filenames and such
let srcs = SourceMap::new();
let pkgs = PackageSet::new(&[]);
- let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, &mut cfg,
+ let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, opts.config,
Layout::at(root.get_absolute_target_dir()),
None, &pkg, Default::default()));
use std::sync::Arc;
use core::registry::PackageRegistry;
-use core::{MultiShell, Source, SourceId, PackageSet, Package, Target, PackageId};
+use core::{Source, SourceId, PackageSet, Package, Target, PackageId};
use core::resolver::Method;
use ops::{self, BuildOutput, ExecEngine};
use sources::{PathSource};
use util::{CargoResult, config, internal, human, ChainError, profile};
/// Contains informations about how a package should be compiled.
-pub struct CompileOptions<'a> {
+pub struct CompileOptions<'a, 'b: 'a> {
pub env: &'a str,
- pub shell: &'a mut MultiShell,
+ pub config: &'a Config<'b>,
/// Number of concurrent jobs to use.
pub jobs: Option<u32>,
/// The target platform to compile for (example: `i686-unknown-linux-gnu`).
}
pub fn compile(manifest_path: &Path,
- options: &mut CompileOptions)
+ options: &CompileOptions)
-> CargoResult<ops::Compilation> {
log!(4, "compile; manifest-path={}", manifest_path.display());
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ options.config));
try!(source.update());
// TODO: Move this into PathSource
debug!("loaded package; package={}", package);
for key in package.get_manifest().get_warnings().iter() {
- try!(options.shell.warn(key))
+ try!(options.config.shell().warn(key))
}
compile_pkg(&package, options)
}
-pub fn compile_pkg(package: &Package, options: &mut CompileOptions)
+pub fn compile_pkg(package: &Package, options: &CompileOptions)
-> CargoResult<ops::Compilation> {
- let CompileOptions { env, ref mut shell, jobs, target, spec,
+ let CompileOptions { env, config, jobs, target, spec,
dev_deps, features, no_default_features,
- lib_only, ref mut exec_engine } = *options;
+ lib_only, ref exec_engine } = *options;
let target = target.map(|s| s.to_string());
let features = features.iter().flat_map(|s| {
return Err(human("features cannot be modified when the main package \
is not being built"))
}
+ if jobs == Some(0) {
+ return Err(human("jobs must be at least 1"))
+ }
- let user_configs = try!(config::all_configs(try!(os::getcwd())));
- let override_ids = try!(source_ids_from_config(&user_configs,
+ let override_ids = try!(source_ids_from_config(config,
package.get_root()));
- let config = try!(Config::new(*shell, jobs, target.clone()));
let (packages, resolve_with_overrides, sources) = {
let rustc_host = config.rustc_host().to_string();
- let mut registry = PackageRegistry::new(&config);
+ let mut registry = PackageRegistry::new(config);
// First, resolve the package's *listed* dependencies, as well as
// downloading and updating all remotes and such.
let ret = {
let _p = profile::start("compiling");
- let lib_overrides = try!(scrape_build_config(&config, &user_configs));
+ let lib_overrides = try!(scrape_build_config(config, jobs, target));
try!(ops::compile_targets(env.as_slice(), targets.as_slice(), to_build,
&PackageSet::new(packages.as_slice()),
&resolve_with_overrides, &sources,
- &config, lib_overrides, exec_engine.clone()))
+ config, lib_overrides, exec_engine.clone()))
};
return Ok(ret);
}
-fn source_ids_from_config(configs: &HashMap<String, config::ConfigValue>,
- cur_path: Path) -> CargoResult<Vec<SourceId>> {
- debug!("loaded config; configs={:?}", configs);
+fn source_ids_from_config(config: &Config, cur_path: Path)
+ -> CargoResult<Vec<SourceId>> {
+ let configs = try!(config.values());
+ debug!("loaded config; configs={:?}", configs);
let config_paths = match configs.get("paths") {
Some(cfg) => cfg,
None => return Ok(Vec::new())
}
fn scrape_build_config(config: &Config,
- configs: &HashMap<String, config::ConfigValue>)
- -> CargoResult<ops::BuildConfig> {
- let target = match configs.get("target") {
- None => return Ok(Default::default()),
+ jobs: Option<u32>,
+ target: Option<String>) -> CargoResult<ops::BuildConfig> {
+ let configs = try!(config.values());
+ let mut base = ops::BuildConfig {
+ jobs: jobs.unwrap_or(os::num_cpus() as u32),
+ requested_target: target.clone(),
+ ..Default::default()
+ };
+ let target_config = match configs.get("target") {
+ None => return Ok(base),
Some(target) => try!(target.table().chain_error(|| {
internal("invalid configuration for the key `target`")
})),
};
- let host = try!(scrape_target_config(target, config.rustc_host()));
- let target = match config.target() {
- Some(triple) => try!(scrape_target_config(target, triple)),
- None => host.clone(),
+ base.host = try!(scrape_target_config(target_config, config.rustc_host()));
+ base.target = match target.as_ref() {
+ Some(triple) => try!(scrape_target_config(target_config, &triple[])),
+ None => base.host.clone(),
};
- Ok(ops::BuildConfig { host: host, target: target })
+ Ok(base)
}
fn scrape_target_config(target: &HashMap<String, config::ConfigValue>,
use std::io::process::Command;
use util::{CargoResult, human};
-pub struct DocOptions<'a> {
+pub struct DocOptions<'a, 'b: 'a> {
pub all: bool,
pub open_result: bool,
- pub compile_opts: ops::CompileOptions<'a>,
+ pub compile_opts: ops::CompileOptions<'a, 'b>,
}
pub fn doc(manifest_path: &Path,
- options: &mut DocOptions) -> CargoResult<()> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ options: &DocOptions) -> CargoResult<()> {
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ options.compile_opts.config));
try!(source.update());
let package = try!(source.get_root_package());
}
}
- try!(ops::compile(manifest_path, &mut options.compile_opts));
+ try!(ops::compile(manifest_path, &options.compile_opts));
if options.open_result {
let name = match options.compile_opts.spec {
-use core::MultiShell;
use core::registry::PackageRegistry;
use core::source::Source;
use ops;
use util::{CargoResult, Config};
/// Executes `cargo fetch`.
-pub fn fetch(manifest_path: &Path,
- shell: &mut MultiShell) -> CargoResult<()> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+pub fn fetch(manifest_path: &Path, config: &Config) -> CargoResult<()> {
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(source.update());
let package = try!(source.get_root_package());
- let mut config = try!(Config::new(shell, None, None));
- let mut registry = PackageRegistry::new(&mut config);
+ let mut registry = PackageRegistry::new(config);
try!(ops::resolve_pkg(&mut registry, &package));
Ok(())
}
use core::PackageId;
use core::registry::PackageRegistry;
-use core::{MultiShell, Source, Resolve};
+use core::{Source, Resolve};
use core::resolver::Method;
use ops;
use sources::{PathSource};
use util::config::{Config};
use util::{CargoResult, human};
-pub struct UpdateOptions<'a> {
- pub shell: &'a mut MultiShell,
+pub struct UpdateOptions<'a, 'b: 'a> {
+ pub config: &'a Config<'b>,
pub to_update: Option<&'a str>,
pub precise: Option<&'a str>,
pub aggressive: bool,
}
-pub fn generate_lockfile(manifest_path: &Path,
- shell: &mut MultiShell)
+pub fn generate_lockfile(manifest_path: &Path, config: &Config)
-> CargoResult<()> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(source.update());
let package = try!(source.get_root_package());
- let mut config = try!(Config::new(shell, None, None));
- let mut registry = PackageRegistry::new(&mut config);
+ let mut registry = PackageRegistry::new(config);
let resolve = try!(ops::resolve_with_previous(&mut registry, &package,
Method::Everything,
None, None));
}
pub fn update_lockfile(manifest_path: &Path,
- opts: &mut UpdateOptions) -> CargoResult<()> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ opts: &UpdateOptions) -> CargoResult<()> {
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ opts.config));
try!(source.update());
let package = try!(source.get_root_package());
simultaneously"))
}
- let mut config = try!(Config::new(opts.shell, None, None));
- let mut registry = PackageRegistry::new(&mut config);
+ let mut registry = PackageRegistry::new(opts.config);
let mut to_avoid = HashSet::new();
match opts.to_update {
use rustc_serialize::{Decodable, Decoder};
-use git2::Config;
+use git2::Config as GitConfig;
-use util::{GitRepo, HgRepo, CargoResult, human, ChainError, config, internal};
-use core::shell::MultiShell;
+use util::{GitRepo, HgRepo, CargoResult, human, ChainError, internal};
+use util::Config;
#[derive(Copy, Show, PartialEq)]
pub enum VersionControl { Git, Hg, NoVcs }
version_control: Option<VersionControl>,
}
-pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> {
- let path = try!(os::getcwd()).join(opts.path);
+pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> {
+ let path = config.cwd().join(opts.path);
if path.exists() {
return Err(human(format!("Destination `{}` already exists",
path.display())))
return Err(human(format!("Invalid character `{}` in crate name: `{}`",
c, name).as_slice()));
}
- mk(&path, name, &opts).chain_error(|| {
+ mk(config, &path, name, &opts).chain_error(|| {
human(format!("Failed to create project `{}` at `{}`",
name, path.display()))
})
GitRepo::discover(path).is_ok() || HgRepo::discover(path).is_ok()
}
-fn mk(path: &Path, name: &str, opts: &NewOptions) -> CargoResult<()> {
- let cfg = try!(global_config());
+fn mk(config: &Config, path: &Path, name: &str,
+ opts: &NewOptions) -> CargoResult<()> {
+ let cfg = try!(global_config(config));
let mut ignore = "/target\n".to_string();
let in_existing_vcs_repo = existing_vcs_repo(&path.dir_path());
if !opts.bin {
}
fn discover_author() -> CargoResult<(String, Option<String>)> {
- let git_config = Config::open_default().ok();
+ let git_config = GitConfig::open_default().ok();
let git_config = git_config.as_ref();
let name = git_config.and_then(|g| g.get_str("user.name").ok())
.map(|s| s.to_string())
Ok((name, email))
}
-fn global_config() -> CargoResult<CargoNewConfig> {
- let user_configs = try!(config::all_configs(try!(os::getcwd())));
+fn global_config(config: &Config) -> CargoResult<CargoNewConfig> {
+ let user_configs = try!(config.values());
let mut cfg = CargoNewConfig {
name: None,
email: None,
use flate2::reader::GzDecoder;
use core::source::{Source, SourceId};
-use core::{Package, MultiShell};
+use core::Package;
use sources::PathSource;
-use util::{CargoResult, human, internal, ChainError};
+use util::{CargoResult, human, internal, ChainError, Config};
use ops;
struct Bomb { path: Option<Path> }
}
pub fn package(manifest_path: &Path,
- shell: &mut MultiShell,
+ config: &Config,
verify: bool,
list: bool,
metadata: bool) -> CargoResult<Option<Path>> {
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(src.update());
let pkg = try!(src.get_root_package());
if metadata {
- try!(check_metadata(&pkg, shell));
+ try!(check_metadata(&pkg, config));
}
if list {
let mut bomb = Bomb { path: Some(dst.clone()) };
- try!(shell.status("Packaging", pkg.get_package_id().to_string()));
- try!(tar(&pkg, &src, shell, &dst).chain_error(|| {
+ try!(config.shell().status("Packaging", pkg.get_package_id().to_string()));
+ try!(tar(&pkg, &src, config, &dst).chain_error(|| {
human("failed to prepare local package for uploading")
}));
if verify {
- try!(run_verify(&pkg, shell, &dst).chain_error(|| {
+ try!(run_verify(config, &pkg, &dst).chain_error(|| {
human("failed to verify package tarball")
}))
}
// check that the package has some piece of metadata that a human can
// use to tell what the package is about.
-fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> {
+fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> {
let md = pkg.get_manifest().get_metadata();
let mut missing = vec![];
}
things.push_str(missing.last().unwrap().as_slice());
- try!(shell.warn(
+ try!(config.shell().warn(
format!("warning: manifest has no {things}. \
See http://doc.crates.io/manifest.html#package-metadata for more info.",
things = things).as_slice()))
Ok(())
}
-fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell,
+fn tar(pkg: &Package, src: &PathSource, config: &Config,
dst: &Path) -> CargoResult<()> {
if dst.exists() {
relative.display()))
}));
let mut file = try!(File::open(file));
- try!(shell.verbose(|shell| {
+ try!(config.shell().verbose(|shell| {
shell.status("Archiving", relative.as_slice())
}));
let path = format!("{}-{}{}{}", pkg.get_name(),
Ok(())
}
-fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path)
+fn run_verify(config: &Config, pkg: &Package, tar: &Path)
-> CargoResult<()> {
- try!(shell.status("Verifying", pkg));
+ try!(config.shell().status("Verifying", pkg));
let f = try!(GzDecoder::new(try!(File::open(tar))));
let dst = pkg.get_root().join(format!("target/package/{}-{}",
// When packages are uploaded to the registry, all path dependencies are
// implicitly converted to registry-based dependencies, so we rewrite those
// dependencies here.
- let registry = try!(SourceId::for_central());
+ let registry = try!(SourceId::for_central(config));
let new_summary = pkg.get_summary().clone().map_dependencies(|d| {
if !d.get_source_id().is_path() { return d }
d.source_id(registry.clone())
pkg.get_package_id().get_source_id());
// Now that we've rewritten all our path dependencies, compile it!
- try!(ops::compile_pkg(&new_pkg, &mut ops::CompileOptions {
+ try!(ops::compile_pkg(&new_pkg, &ops::CompileOptions {
env: "compile",
- shell: shell,
+ config: config,
jobs: None,
target: None,
dev_deps: false,
use ops;
-use core::{MultiShell, Source, PackageIdSpec};
+use core::{Source, PackageIdSpec};
use sources::{PathSource};
-use util::{CargoResult, human};
+use util::{CargoResult, human, Config};
pub fn pkgid(manifest_path: &Path,
spec: Option<&str>,
- _shell: &mut MultiShell) -> CargoResult<PackageIdSpec> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ config: &Config) -> CargoResult<PackageIdSpec> {
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(source.update());
let package = try!(source.get_root_package());
use std::collections::HashSet;
-use std::io::{self, File, fs};
+use std::error::FromError;
use std::io::fs::PathExtensions;
+use std::io::{self, File, fs};
use core::{Package,Manifest,SourceId};
-use util::{self, CargoResult, human};
+use util::{self, CargoResult, human, Config};
use util::important_paths::find_project_manifest_exact;
use util::toml::{Layout, project_layout};
-use std::error::FromError;
-pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId)
+pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId,
+ config: &Config)
-> CargoResult<(Manifest, Vec<Path>)> {
let root = layout.root.clone();
- util::toml::to_manifest(contents, source_id, layout).map_err(|e| {
+ util::toml::to_manifest(contents, source_id, layout, config).map_err(|e| {
human(format!("failed to parse manifest at `{:?}`\n{}",
root.join("Cargo.toml"), e))
})
}
-pub fn read_package(path: &Path, source_id: &SourceId)
- -> CargoResult<(Package, Vec<Path>)> {
+pub fn read_package(path: &Path, source_id: &SourceId, config: &Config)
+ -> CargoResult<(Package, Vec<Path>)> {
log!(5, "read_package; path={}; source-id={}", path.display(), source_id);
let mut file = try!(File::open(path));
let data = try!(file.read_to_end());
let layout = project_layout(&path.dir_path());
let (manifest, nested) =
- try!(read_manifest(data.as_slice(), layout, source_id));
+ try!(read_manifest(data.as_slice(), layout, source_id, config));
Ok((Package::new(manifest, path, source_id), nested))
}
-pub fn read_packages(path: &Path,
- source_id: &SourceId) -> CargoResult<Vec<Package>> {
+pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config)
+ -> CargoResult<Vec<Package>> {
let mut all_packages = HashSet::new();
let mut visited = HashSet::<Path>::new();
}
if has_manifest(dir) {
- try!(read_nested_packages(dir, &mut all_packages, source_id,
+ try!(read_nested_packages(dir, &mut all_packages, source_id, config,
&mut visited));
}
Ok(true)
fn read_nested_packages(path: &Path,
all_packages: &mut HashSet<Package>,
source_id: &SourceId,
+ config: &Config,
visited: &mut HashSet<Path>) -> CargoResult<()> {
if !visited.insert(path.clone()) { return Ok(()) }
let manifest = try!(find_project_manifest_exact(path, "Cargo.toml"));
- let (pkg, nested) = try!(read_package(&manifest, source_id));
+ let (pkg, nested) = try!(read_package(&manifest, source_id, config));
all_packages.insert(pkg);
// Registry sources are not allowed to have `path=` dependencies because
if !source_id.is_registry() {
for p in nested.iter() {
try!(read_nested_packages(&path.join(p), all_packages, source_id,
- visited));
+ config, visited));
}
}
pub fn run(manifest_path: &Path,
target_kind: TargetKind,
name: Option<String>,
- options: &mut ops::CompileOptions,
+ options: &ops::CompileOptions,
args: &[String]) -> CargoResult<Option<ProcessError>> {
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let config = options.config;
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), config));
try!(src.update());
let root = try!(src.get_root_package());
let env = options.env;
.args(args)
.cwd(try!(os::getcwd()));
- try!(options.shell.status("Running", process.to_string()));
+ try!(config.shell().status("Running", process.to_string()));
Ok(process.exec().err())
}
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::hash_map::HashMap;
-use std::os;
use std::str;
use std::sync::Arc;
}
pub struct Context<'a, 'b: 'a> {
- pub config: &'b Config<'b>,
+ pub config: &'a Config<'b>,
pub resolve: &'a Resolve,
- pub sources: &'a SourceMap<'b>,
+ pub sources: &'a SourceMap<'a>,
pub compilation: Compilation,
pub build_state: Arc<BuildState>,
pub exec_engine: Arc<Box<ExecEngine>>,
- pub cwd: Path,
env: &'a str,
host: Layout,
}
impl<'a, 'b: 'a> Context<'a, 'b> {
- pub fn new(env: &'a str, resolve: &'a Resolve, sources: &'a SourceMap<'b>,
- deps: &'a PackageSet, config: &'b Config<'b>,
- host: Layout, target: Option<Layout>,
+ pub fn new(env: &'a str,
+ resolve: &'a Resolve,
+ sources: &'a SourceMap<'a>,
+ deps: &'a PackageSet,
+ config: &'a Config<'b>,
+ host: Layout,
+ target_layout: Option<Layout>,
root_pkg: &Package,
- build_config: BuildConfig)
- -> CargoResult<Context<'a, 'b>> {
- let (target_dylib, target_exe) =
- try!(Context::filename_parts(config.target()));
- let (host_dylib, host_exe) = if config.target().is_none() {
- (target_dylib.clone(),
- target_exe.clone())
+ build_config: BuildConfig) -> CargoResult<Context<'a, 'b>> {
+ let target = build_config.requested_target.clone();
+ let target = target.as_ref().map(|s| &s[]);
+ let (target_dylib, target_exe) = try!(Context::filename_parts(target));
+ let (host_dylib, host_exe) = if build_config.requested_target.is_none() {
+ (target_dylib.clone(), target_exe.clone())
} else {
try!(Context::filename_parts(None))
};
- let target_triple = config.target().map(|s| s.to_string());
- let target_triple = target_triple.unwrap_or(config.rustc_host().to_string());
- let cwd = try!(os::getcwd().chain_error(|| {
- human("failed to get the current directory")
- }));
+ let target_triple = target.unwrap_or(config.rustc_host()).to_string();
Ok(Context {
target_triple: target_triple,
env: env,
host: host,
- target: target,
+ target: target_layout,
resolve: resolve,
sources: sources,
package_set: deps,
build_state: Arc::new(BuildState::new(build_config.clone(), deps)),
build_config: build_config,
exec_engine: Arc::new(Box::new(ProcessEngine) as Box<ExecEngine>),
- cwd: cwd,
})
}
self.build_requirements(pkg, target, Platform::Target);
}
+ let jobs = self.jobs();
self.compilation.extra_env.insert("NUM_JOBS".to_string(),
- Some(self.config.jobs().to_string()));
+ Some(jobs.to_string()));
self.compilation.root_output =
self.layout(pkg, Kind::Target).proxy().dest().clone();
self.compilation.deps_output =
Kind::Target => &self.build_config.target,
}
}
+
+ /// Number of jobs specified for this build
+ pub fn jobs(&self) -> u32 { self.build_config.jobs }
+
+ /// Requested (not actual) target for the build
+ pub fn requested_target(&self) -> Option<&str> {
+ self.build_config.requested_target.as_ref().map(|s| &s[])
+ }
}
impl Platform {
.env("CARGO_MANIFEST_DIR", Some(pkg.get_manifest_path()
.dir_path()
.display().to_string()))
- .env("NUM_JOBS", Some(cx.config.jobs().to_string()))
+ .env("NUM_JOBS", Some(cx.jobs().to_string()))
.env("TARGET", Some(match kind {
Kind::Host => cx.config.rustc_host(),
Kind::Target => cx.target_triple(),
type Message = (PackageId, Stage, Freshness, CargoResult<()>);
impl<'a, 'b> JobQueue<'a, 'b> {
- pub fn new(resolve: &'a Resolve, packages: &'a PackageSet,
- config: &Config) -> JobQueue<'a, 'b> {
+ pub fn new(resolve: &'a Resolve, packages: &'a PackageSet, jobs: u32)
+ -> JobQueue<'a, 'b> {
let (tx, rx) = channel();
JobQueue {
- pool: TaskPool::new(config.jobs() as usize),
+ pool: TaskPool::new(jobs as usize),
queue: DependencyQueue::new(),
tx: tx,
rx: rx,
pub struct BuildConfig {
pub host: TargetConfig,
pub target: TargetConfig,
+ pub jobs: u32,
+ pub requested_target: Option<String>,
}
#[derive(Clone, Default)]
// Returns a mapping of the root package plus its immediate dependencies to
// where the compiled libraries are all located.
-pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
- deps: &PackageSet, resolve: &'a Resolve,
- sources: &'a SourceMap,
- config: &'a Config<'a>,
- build_config: BuildConfig,
- exec_engine: Option<Arc<Box<ExecEngine>>>)
- -> CargoResult<Compilation> {
+pub fn compile_targets<'a, 'b>(env: &str,
+ targets: &[&'a Target],
+ pkg: &'a Package,
+ deps: &PackageSet,
+ resolve: &'a Resolve,
+ sources: &'a SourceMap<'a>,
+ config: &'a Config<'b>,
+ build_config: BuildConfig,
+ exec_engine: Option<Arc<Box<ExecEngine>>>)
+ -> CargoResult<Compilation> {
if targets.is_empty() {
return Ok(Compilation::new(pkg))
}
deps.iter().find(|p| p.get_package_id() == resolve.root()).unwrap()
};
let host_layout = Layout::new(root, None, dest);
- let target_layout = config.target().map(|target| {
- layout::Layout::new(root, Some(target), dest)
+ let target_layout = build_config.requested_target.as_ref().map(|target| {
+ layout::Layout::new(root, Some(&target[]), dest)
});
let mut cx = try!(Context::new(env, resolve, sources, deps, config,
cx.exec_engine = exec_engine.clone();
}
- let mut queue = JobQueue::new(cx.resolve, deps, cx.config);
+ let mut queue = JobQueue::new(cx.resolve, deps, cx.jobs());
// First ensure that the destination directory exists
try!(cx.prepare(pkg));
// Prepare the fingerprint directory as the first step of building a package
let (target1, target2) = fingerprint::prepare_init(cx, pkg, Kind::Target);
let mut init = vec![(Job::new(target1, target2), Fresh)];
- if cx.config.target().is_some() {
+ if cx.requested_target().is_some() {
let (plugin1, plugin2) = fingerprint::prepare_init(cx, pkg, Kind::Host);
init.push((Job::new(plugin1, plugin2), Fresh));
}
Platform::Target => reqs.push(Platform::Target),
Platform::Plugin => reqs.push(Platform::Plugin),
Platform::PluginAndTarget => {
- if cx.config.target().is_some() {
+ if cx.requested_target().is_some() {
reqs.push(Platform::Plugin);
reqs.push(Platform::Target);
} else {
let rustc_dep_info_loc = root.join(target.file_stem()).with_extension("d");
let dep_info_loc = fingerprint::dep_info_loc(cx, package, target, kind);
- let cwd = cx.cwd.clone();
+ let cwd = cx.config.cwd().clone();
Ok((Work::new(move |desc_tx| {
let mut rustc = rustc;
Ok(match req {
Platform::Target => vec![(target_cmd, Kind::Target)],
Platform::Plugin => vec![(plugin_cmd, Kind::Host)],
- Platform::PluginAndTarget if cx.config.target().is_none() =>
+ Platform::PluginAndTarget if cx.requested_target().is_none() =>
vec![(target_cmd, Kind::Target)],
Platform::PluginAndTarget => vec![(target_cmd, Kind::Target),
(plugin_cmd, Kind::Host)],
let cx_root = cx.layout(package, kind).proxy().dest().join("doc");
let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx));
let mut rustdoc = rustdoc.arg(root_path(cx, package, target))
- .cwd(cx.cwd.clone())
+ .cwd(cx.config.cwd().clone())
.arg("-o").arg(cx_root)
.arg("--crate-name").arg(target.get_name());
// absolute paths instead of relative paths.
fn root_path(cx: &Context, pkg: &Package, target: &Target) -> Path {
let absolute = pkg.get_root().join(target.get_src_path());
- absolute.path_relative_from(&cx.cwd).unwrap_or(absolute)
+ absolute.path_relative_from(cx.config.cwd()).unwrap_or(absolute)
}
fn build_base_args(cx: &Context,
let metadata = target.get_metadata();
// Move to cwd so the root_path() passed below is actually correct
- cmd = cmd.cwd(cx.cwd.clone());
+ cmd = cmd.cwd(cx.config.cwd().clone());
// TODO: Handle errors in converting paths into args
cmd = cmd.arg(root_path(cx, pkg, target));
}
}
- cmd = opt(cmd, "--target", "", cx.config.target());
+ cmd = opt(cmd, "--target", "", cx.requested_target());
cmd = opt(cmd, "-C", "ar=", cx.ar(kind));
cmd = opt(cmd, "-C", "linker=", cx.linker(kind));
}
use ops::{self, ExecEngine, ProcessEngine};
use util::{CargoResult, ProcessError};
-pub struct TestOptions<'a> {
- pub compile_opts: ops::CompileOptions<'a>,
+pub struct TestOptions<'a, 'b: 'a> {
+ pub compile_opts: ops::CompileOptions<'a, 'b>,
pub no_run: bool,
pub name: Option<&'a str>,
}
pub fn run_tests(manifest_path: &Path,
- options: &mut TestOptions,
+ options: &TestOptions,
test_args: &[String]) -> CargoResult<Option<ProcessError>> {
- let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let config = options.compile_opts.config;
+ let mut source = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(source.update());
- let mut compile = try!(ops::compile(manifest_path, &mut options.compile_opts));
+ let mut compile = try!(ops::compile(manifest_path, &options.compile_opts));
if options.no_run { return Ok(None) }
compile.tests.sort();
};
let cmd = try!(compile.target_process(exe, &compile.package))
.args(test_args);
- try!(options.compile_opts.shell.concise(|shell| {
+ try!(config.shell().concise(|shell| {
shell.status("Running", to_display.display().to_string())
}));
- try!(options.compile_opts.shell.verbose(|shell| {
+ try!(config.shell().verbose(|shell| {
shell.status("Running", cmd.to_string())
}));
match ExecEngine::exec(&mut ProcessEngine, cmd) {
});
for (lib, name) in libs {
- try!(options.compile_opts.shell.status("Doc-tests", name));
+ try!(config.shell().status("Doc-tests", name));
let mut p = try!(compile.rustdoc_process(&compile.package))
.arg("--test").arg(lib)
.arg("--crate-name").arg(name)
}
}
- try!(options.compile_opts.shell.verbose(|shell| {
+ try!(config.shell().verbose(|shell| {
shell.status("Running", p.to_string())
}));
match ExecEngine::exec(&mut ProcessEngine, p) {
}
pub fn run_benches(manifest_path: &Path,
- options: &mut TestOptions,
+ options: &TestOptions,
args: &[String]) -> CargoResult<Option<ProcessError>> {
let mut args = args.to_vec();
args.push("--bench".to_string());
use term::color::BLACK;
use core::source::Source;
-use core::{Package, MultiShell, SourceId};
+use core::{Package, SourceId};
use core::dependency::Kind;
use core::manifest::ManifestMetadata;
use ops;
}
pub fn publish(manifest_path: &Path,
- shell: &mut MultiShell,
+ config: &Config,
token: Option<String>,
index: Option<String>,
verify: bool) -> CargoResult<()> {
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(src.update());
let pkg = try!(src.get_root_package());
- let (mut registry, reg_id) = try!(registry(shell, token, index));
+ let (mut registry, reg_id) = try!(registry(config, token, index));
try!(verify_dependencies(&pkg, ®_id));
// Prepare a tarball, with a non-surpressable warning if metadata
// is missing since this is being put online.
- let tarball = try!(ops::package(manifest_path, shell, verify, false, true)).unwrap();
+ let tarball = try!(ops::package(manifest_path, config, verify,
+ false, true)).unwrap();
// Upload said tarball to the specified destination
- try!(shell.status("Uploading", pkg.get_package_id().to_string()));
+ try!(config.shell().status("Uploading", pkg.get_package_id().to_string()));
try!(transmit(&pkg, &tarball, &mut registry));
Ok(())
})
}
-pub fn registry_configuration() -> CargoResult<RegistryConfig> {
- let configs = try!(config::all_configs(try!(os::getcwd())));
+pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
+ let configs = try!(config.values());
let registry = match configs.get("registry") {
None => return Ok(RegistryConfig { index: None, token: None }),
Some(registry) => try!(registry.table().chain_error(|| {
Ok(RegistryConfig { index: index, token: token })
}
-pub fn registry(shell: &mut MultiShell,
+pub fn registry(config: &Config,
token: Option<String>,
index: Option<String>) -> CargoResult<(Registry, SourceId)> {
// Parse all configuration options
let RegistryConfig {
token: token_config,
index: index_config,
- } = try!(registry_configuration());
+ } = try!(registry_configuration(config));
let token = token.or(token_config);
let index = index.or(index_config).unwrap_or(RegistrySource::default_url());
let index = try!(index.as_slice().to_url().map_err(human));
let sid = SourceId::for_registry(&index);
let api_host = {
- let mut config = try!(Config::new(shell, None, None));
- let mut src = RegistrySource::new(&sid, &mut config);
+ let mut src = RegistrySource::new(&sid, config);
try!(src.update().chain_error(|| {
human(format!("Failed to update registry {}", index))
}));
(try!(src.config())).api
};
- let handle = try!(http_handle());
+ let handle = try!(http_handle(config));
Ok((Registry::new_handle(api_host, token, handle), sid))
}
/// Create a new HTTP handle with appropriate global configuration for cargo.
-pub fn http_handle() -> CargoResult<http::Handle> {
- Ok(match try!(http_proxy()) {
+pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
+ Ok(match try!(http_proxy(config)) {
Some(proxy) => http::handle().proxy(proxy),
None => http::handle(),
})
///
/// Favor cargo's `http.proxy`, then git's `http.proxy`, then finally a
/// HTTP_PROXY env var.
-pub fn http_proxy() -> CargoResult<Option<String>> {
- let configs = try!(config::all_configs(try!(os::getcwd())));
+pub fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
+ let configs = try!(config.values());
match configs.get("http") {
Some(http) => {
let http = try!(http.table().chain_error(|| {
Ok(os::getenv("HTTP_PROXY"))
}
-pub fn registry_login(shell: &mut MultiShell, token: String) -> CargoResult<()> {
- let config = try!(Config::new(shell, None, None));
- let RegistryConfig { index, token: _ } = try!(registry_configuration());
+pub fn registry_login(config: &Config, token: String) -> CargoResult<()> {
+ let RegistryConfig { index, token: _ } = try!(registry_configuration(config));
let mut map = HashMap::new();
let p = try!(os::getcwd());
match index {
}
map.insert("token".to_string(), ConfigValue::String(token, p));
- config::set_config(&config, Location::Global, "registry",
+ config::set_config(config, Location::Global, "registry",
ConfigValue::Table(map))
}
pub list: bool,
}
-pub fn modify_owners(shell: &mut MultiShell,
- opts: &OwnersOptions) -> CargoResult<()> {
+pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
let name = match opts.krate {
Some(ref name) => name.clone(),
None => {
let manifest_path = try!(find_root_manifest_for_cwd(None));
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(src.update());
let pkg = try!(src.get_root_package());
pkg.get_name().to_string()
}
};
- let (mut registry, _) = try!(registry(shell, opts.token.clone(),
+ let (mut registry, _) = try!(registry(config, opts.token.clone(),
opts.index.clone()));
match opts.to_add {
Some(ref v) => {
let v = v.iter().map(|s| s.as_slice()).collect::<Vec<_>>();
- try!(shell.status("Owner", format!("adding `{:#?}` to `{}`", v, name)));
+ try!(config.shell().status("Owner", format!("adding `{:#?}` to `{}`",
+ v, name)));
try!(registry.add_owners(name.as_slice(), v.as_slice()).map_err(|e| {
human(format!("failed to add owners: {}", e))
}));
match opts.to_remove {
Some(ref v) => {
let v = v.iter().map(|s| s.as_slice()).collect::<Vec<_>>();
- try!(shell.status("Owner", format!("removing `{:?}` from `{}`",
- v, name)));
+ try!(config.shell().status("Owner", format!("removing `{:?}` from `{}`",
+ v, name)));
try!(registry.remove_owners(name.as_slice(), v.as_slice()).map_err(|e| {
human(format!("failed to add owners: {}", e))
}));
Ok(())
}
-pub fn yank(shell: &mut MultiShell,
+pub fn yank(config: &Config,
krate: Option<String>,
version: Option<String>,
token: Option<String>,
Some(name) => name,
None => {
let manifest_path = try!(find_root_manifest_for_cwd(None));
- let mut src = try!(PathSource::for_path(&manifest_path.dir_path()));
+ let mut src = try!(PathSource::for_path(&manifest_path.dir_path(),
+ config));
try!(src.update());
let pkg = try!(src.get_root_package());
pkg.get_name().to_string()
None => return Err(human("a version must be specified to yank"))
};
- let (mut registry, _) = try!(registry(shell, token, index));
+ let (mut registry, _) = try!(registry(config, token, index));
if undo {
- try!(shell.status("Unyank", format!("{}:{}", name, version)));
+ try!(config.shell().status("Unyank", format!("{}:{}", name, version)));
try!(registry.unyank(name.as_slice(), version.as_slice()).map_err(|e| {
human(format!("failed to undo a yank: {}", e))
}));
} else {
- try!(shell.status("Yank", format!("{}:{}", name, version)));
+ try!(config.shell().status("Yank", format!("{}:{}", name, version)));
try!(registry.yank(name.as_slice(), version.as_slice()).map_err(|e| {
human(format!("failed to yank: {}", e))
}));
Ok(())
}
-pub fn search(query: &str, shell: &mut MultiShell, index: Option<String>) -> CargoResult<()> {
+pub fn search(query: &str, config: &Config, index: Option<String>) -> CargoResult<()> {
fn truncate_with_ellipsis(s: &str, max_length: usize) -> String {
if s.len() < max_length {
s.to_string()
}
}
- let (mut registry, _) = try!(registry(shell, None, index));
-
+ let (mut registry, _) = try!(registry(config, None, index));
let crates = try!(registry.search(query).map_err(|e| {
human(format!("failed to retrieve search results from the registry: {}", e))
}));
}
None => name
};
- try!(shell.say(line, BLACK));
+ try!(config.shell().say(line, BLACK));
}
Ok(())
db_path: Path,
checkout_path: Path,
source_id: SourceId,
- path_source: Option<PathSource>,
+ path_source: Option<PathSource<'a, 'b>>,
rev: Option<GitRevision>,
config: &'a Config<'b>,
}
try!(repo.copy_to(actual_rev.clone(), &self.checkout_path));
let source_id = self.source_id.with_precise(Some(actual_rev.to_string()));
- let path_source = PathSource::new(&self.checkout_path, &source_id);
+ let path_source = PathSource::new(&self.checkout_path, &source_id,
+ self.config);
self.path_source = Some(path_source);
self.rev = Some(actual_rev);
use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry};
use ops;
-use util::{CargoResult, internal, internal_error, human, ChainError};
+use util::{CargoResult, internal, internal_error, human, ChainError, Config};
-pub struct PathSource {
+pub struct PathSource<'a, 'b: 'a> {
id: SourceId,
path: Path,
updated: bool,
- packages: Vec<Package>
+ packages: Vec<Package>,
+ config: &'a Config<'b>,
}
// TODO: Figure out if packages should be discovered in new or self should be
// mut and packages are discovered in update
-impl PathSource {
-
- pub fn for_path(path: &Path) -> CargoResult<PathSource> {
+impl<'a, 'b> PathSource<'a, 'b> {
+ pub fn for_path(path: &Path, config: &'a Config<'b>)
+ -> CargoResult<PathSource<'a, 'b>> {
log!(5, "PathSource::for_path; path={}", path.display());
- Ok(PathSource::new(path, &try!(SourceId::for_path(path))))
+ Ok(PathSource::new(path, &try!(SourceId::for_path(path)), config))
}
/// Invoked with an absolute path to a directory that contains a Cargo.toml.
/// The source will read the manifest and find any other packages contained
/// in the directory structure reachable by the root manifest.
- pub fn new(path: &Path, id: &SourceId) -> PathSource {
+ pub fn new(path: &Path, id: &SourceId, config: &'a Config<'b>)
+ -> PathSource<'a, 'b> {
log!(5, "new; id={}", id);
PathSource {
id: id.clone(),
path: path.clone(),
updated: false,
- packages: Vec::new()
+ packages: Vec::new(),
+ config: config,
}
}
if self.updated {
Ok(self.packages.clone())
} else {
- ops::read_packages(&self.path, &self.id)
+ ops::read_packages(&self.path, &self.id, self.config)
}
}
}
}
-impl Show for PathSource {
+impl<'a, 'b> Show for PathSource<'a, 'b> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "the paths source")
}
}
-impl Registry for PathSource {
+impl<'a, 'b> Registry for PathSource<'a, 'b> {
fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
let mut summaries: Vec<Summary> = self.packages.iter()
.map(|p| p.get_summary().clone())
}
}
-impl Source for PathSource {
+impl<'a, 'b> Source for PathSource<'a, 'b> {
fn update(&mut self) -> CargoResult<()> {
if !self.updated {
let packages = try!(self.read_packages());
src_path: Path,
config: &'a Config<'b>,
handle: Option<http::Handle>,
- sources: Vec<PathSource>,
+ sources: Vec<PathSource<'a, 'b>>,
hashes: HashMap<(String, String), String>, // (name, vers) => cksum
cache: HashMap<String, Vec<(Summary, bool)>>,
updated: bool,
///
/// This is the main cargo registry by default, but it can be overridden in
/// a .cargo/config
- pub fn url() -> CargoResult<Url> {
- let config = try!(ops::registry_configuration());
+ pub fn url(config: &Config) -> CargoResult<Url> {
+ let config = try!(ops::registry_configuration(config));
let url = config.index.unwrap_or(DEFAULT.to_string());
url.as_slice().to_url().map_err(human)
}
let handle = match self.handle {
Some(ref mut handle) => handle,
None => {
- self.handle = Some(try!(ops::http_handle()));
+ self.handle = Some(try!(ops::http_handle(self.config)));
self.handle.as_mut().unwrap()
}
};
let path = try!(self.unpack_package(package, path).chain_error(|| {
internal(format!("Failed to unpack package `{}`", package))
}));
- let mut src = PathSource::new(&path, &self.source_id);
+ let mut src = PathSource::new(&path, &self.source_id, self.config);
try!(src.update());
self.sources.push(src);
}
use std::{fmt, os, mem};
-use std::cell::{RefCell, RefMut};
+use std::cell::{RefCell, RefMut, Ref, Cell};
use std::collections::hash_map::{HashMap};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::io;
use std::io::fs::{self, PathExtensions, File};
-use std::string;
use rustc_serialize::{Encodable,Encoder};
use toml;
pub struct Config<'a> {
home_path: Path,
shell: RefCell<&'a mut MultiShell>,
- jobs: u32,
- target: Option<string::String>,
- rustc_version: string::String,
+ rustc_version: String,
/// The current host and default target of rustc
- rustc_host: string::String,
+ rustc_host: String,
+ values: RefCell<HashMap<String, ConfigValue>>,
+ values_loaded: Cell<bool>,
+ cwd: Path,
}
impl<'a> Config<'a> {
- pub fn new(shell: &'a mut MultiShell,
- jobs: Option<u32>,
- target: Option<string::String>) -> CargoResult<Config<'a>> {
- if jobs == Some(0) {
- return Err(human("jobs must be at least 1"))
- }
-
+ pub fn new(shell: &'a mut MultiShell) -> CargoResult<Config<'a>> {
+ let cwd = try!(os::getcwd().chain_error(|| {
+ human("couldn't get the current directory of the process")
+ }));
let (rustc_version, rustc_host) = try!(ops::rustc_version());
Ok(Config {
This probably means that $HOME was not set.")
})),
shell: RefCell::new(shell),
- jobs: jobs.unwrap_or(os::num_cpus() as u32),
- target: target,
rustc_version: rustc_version,
rustc_host: rustc_host,
+ cwd: cwd,
+ values: RefCell::new(HashMap::new()),
+ values_loaded: Cell::new(false),
})
}
self.shell.borrow_mut()
}
- pub fn jobs(&self) -> u32 {
- self.jobs
- }
-
- pub fn target(&self) -> Option<&str> {
- self.target.as_ref().map(|t| t.as_slice())
- }
-
/// Return the output of `rustc -v verbose`
pub fn rustc_version(&self) -> &str {
self.rustc_version.as_slice()
pub fn rustc_host(&self) -> &str {
self.rustc_host.as_slice()
}
+
+ pub fn values(&self) -> CargoResult<Ref<HashMap<String, ConfigValue>>> {
+ if !self.values_loaded.get() {
+ try!(self.load_values());
+ self.values_loaded.set(true);
+ }
+ Ok(self.values.borrow())
+ }
+
+ pub fn cwd(&self) -> &Path { &self.cwd }
+
+ fn load_values(&self) -> CargoResult<()> {
+ *self.values.borrow_mut() = try!(all_configs(&self.cwd));
+ Ok(())
+ }
}
#[derive(Eq, PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
#[derive(Eq,PartialEq,Clone,RustcDecodable)]
pub enum ConfigValue {
- String(string::String, Path),
- List(Vec<(string::String, Path)>),
- Table(HashMap<string::String, ConfigValue>),
+ String(String, Path),
+ List(Vec<(String, Path)>),
+ Table(HashMap<String, ConfigValue>),
Boolean(bool, Path),
}
match *self {
CV::String(ref string, _) => string.encode(s),
CV::List(ref list) => {
- let list: Vec<&string::String> = list.iter().map(|s| &s.0).collect();
+ let list: Vec<&String> = list.iter().map(|s| &s.0).collect();
list.encode(s)
}
CV::Table(ref table) => table.encode(s),
}
}
- pub fn table(&self) -> CargoResult<&HashMap<string::String, ConfigValue>> {
+ pub fn table(&self) -> CargoResult<&HashMap<String, ConfigValue>> {
match *self {
CV::Table(ref table) => Ok(table),
_ => Err(internal(format!("expected a table, but found a {}",
}
}
- pub fn list(&self) -> CargoResult<&[(string::String, Path)]> {
+ pub fn list(&self) -> CargoResult<&[(String, Path)]> {
match *self {
CV::List(ref list) => Ok(list.as_slice()),
_ => Err(internal(format!("expected a list, but found a {}",
human(format!("`{}` not found in your configuration", key)))
}
-pub fn all_configs(pwd: Path) -> CargoResult<HashMap<string::String, ConfigValue>> {
+pub fn all_configs(pwd: &Path) -> CargoResult<HashMap<String, ConfigValue>> {
let mut cfg = CV::Table(HashMap::new());
- try!(walk_tree(&pwd, |mut file| {
+ try!(walk_tree(pwd, |mut file| {
let path = file.path().clone();
let contents = try!(file.read_to_string());
let table = try!(cargo_toml::parse(contents.as_slice(), &path).chain_error(|| {
use core::dependency::Kind;
use core::manifest::{LibKind, Profile, ManifestMetadata};
use core::package_id::Metadata;
-use util::{CargoResult, human, ToUrl, ToSemver, ChainError};
+use util::{CargoResult, human, ToUrl, ToSemver, ChainError, Config};
/// Representation of the projects file layout.
///
pub fn to_manifest(contents: &[u8],
source_id: &SourceId,
- layout: Layout)
+ layout: Layout,
+ config: &Config)
-> CargoResult<(Manifest, Vec<Path>)> {
let manifest = layout.root.join("Cargo.toml");
let manifest = match manifest.path_relative_from(&try!(os::getcwd())) {
manifest.display(), e)))
};
- let pair = try!(toml_manifest.to_manifest(source_id, &layout).map_err(|err| {
+ let pair = try!(toml_manifest.to_manifest(source_id, &layout, config).map_err(|err| {
human(format!("{} is not a valid manifest\n\n{}",
manifest.display(), err))
}));
}
}
-struct Context<'a> {
+struct Context<'a, 'b, 'c: 'b> {
deps: &'a mut Vec<Dependency>,
source_id: &'a SourceId,
- nested_paths: &'a mut Vec<Path>
+ nested_paths: &'a mut Vec<Path>,
+ config: &'b Config<'c>,
}
// These functions produce the equivalent of specific manifest entries. One
}
impl TomlManifest {
- pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout)
+ pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout,
+ config: &Config)
-> CargoResult<(Manifest, Vec<Path>)> {
let mut nested_paths = vec!();
let mut cx = Context {
deps: &mut deps,
source_id: source_id,
- nested_paths: &mut nested_paths
+ nested_paths: &mut nested_paths,
+ config: config,
};
// Collect the deps
cx.source_id.clone()
})
}
- }.unwrap_or(try!(SourceId::for_central()));
+ }.unwrap_or(try!(SourceId::for_central(cx.config)));
let dep = try!(Dependency::parse(n.as_slice(),
details.version.as_ref()
-use std::io::fs::{self, PathExtensions};
+use std::io::fs;
use std::io;
use std::io::{USER_RWX, File};
use std::os;
proj
}
-// We can't entirely obliterate PATH because windows needs it for paths to
-// things like libgcc, but we want to filter out everything which has a `cargo`
-// installation as we don't want it to muck with the --list tests
-fn new_path() -> Vec<Path> {
+fn path() -> Vec<Path> {
let path = os::getenv_as_bytes("PATH").unwrap_or(Vec::new());
- os::split_paths(path).into_iter().filter(|p| {
- !p.join(format!("cargo{}", os::consts::EXE_SUFFIX)).exists()
- }).collect()
+ os::split_paths(path)
}
test!(list_commands_looks_at_path {
let proj = project("list-non-overlapping");
.cwd(proj.root())
.env("HOME", Some(paths::home()));
- let mut path = new_path();
+ let mut path = path();
path.push(proj.root().join("path-test"));
let path = os::join_paths(path.as_slice()).unwrap();
let output = pr.arg("-v").arg("--list").env("PATH", Some(path.as_slice()));
// By default, not transitive updates
println!("dep1 update");
- assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1"),
+ assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+ .arg("-p").arg("dep1"),
execs().with_stdout(""));
// Specifying a precise rev to the old rev shouldn't actually update
// anything because we already have the rev in the db.
println!("bar precise update");
- assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar")
+ assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+ .arg("-p").arg("bar")
.arg("--precise").arg(old_head.to_string()),
execs().with_stdout(""));
// Updating aggressively should, however, update the repo.
println!("dep1 aggressive update");
- assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1")
+ assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+ .arg("-p").arg("dep1")
.arg("--aggressive"),
execs().with_stdout(format!("{} git repository `{}`",
UPDATING,
compiling = COMPILING, dir = p.url())));
// We should be able to update transitive deps
- assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar"),
+ assert_that(p.process(cargo_dir().join("cargo")).arg("update")
+ .arg("-p").arg("bar"),
execs().with_stdout(format!("{} git repository `{}`",
UPDATING,
git_project.url())));